package top.huhuiyu.spirngboot2.total.service.impl;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import top.huhuiyu.spirngboot2.total.base.BaseDataResult;
import top.huhuiyu.spirngboot2.total.base.BaseResult;
import top.huhuiyu.spirngboot2.total.dao.TbFileDAO;
import top.huhuiyu.spirngboot2.total.entity.AuthInfo;
import top.huhuiyu.spirngboot2.total.entity.TbFile;
import top.huhuiyu.spirngboot2.total.service.FileService;
import top.huhuiyu.spirngboot2.total.utils.AuthInfoUtils;
import top.huhuiyu.spirngboot2.total.utils.JsonUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;

@Service
@RequiredArgsConstructor
public class FileServiceImpl implements FileService {
    private final TbFileDAO tbFileDAO;
    public static final String UPLOAD_PATH = "./files/";
    public static final int BUFF_SIZE = 8 * 1024;
    private static final String FILE_NAME = "_%s_%s";

    public void copy(InputStream is, OutputStream out) {
        byte[] bytes = new byte[BUFF_SIZE];
        try {
            int len = is.read(bytes);
            while (len > 0) {
                out.write(bytes, 0, len);
                out.flush();
                len = is.read(bytes);
            }
            out.close();
            is.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void download(Integer fid, HttpServletResponse response) {
        // 查询文件信息
        TbFile tbFile = tbFileDAO.selectById(fid);
        BaseResult result;
        if (tbFile == null) {
            result = BaseResult.fail("文件不存在");
            try {
                response.reset();
                response.setContentType("text/plain;charset=UTF-8");
                response.getWriter().write(JsonUtils.stringify(result));
                response.getWriter().flush();
                response.getWriter().close();
                return;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        // 自定义应答
        String filename = String.format(FILE_NAME, fid, tbFile.getFileName());
        File file = new File(UPLOAD_PATH, filename);
        response.reset();
        response.setContentType(tbFile.getContentType());
        byte[] filenamebytes = filename.getBytes(StandardCharsets.UTF_8);
        response.setHeader("Content-Disposition", "attachment;filename="
                + new String(filenamebytes, 0, filenamebytes.length,
                StandardCharsets.ISO_8859_1));
        try {
            copy(new FileInputStream(file), response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    @Transactional
    public BaseDataResult<TbFile> upload(TbFile tbFile, MultipartFile fileinfo) {
        AuthInfo authInfo = AuthInfoUtils.authInfo();
        // 保存文件信息到数据库
        tbFile.setUid(authInfo.getUserId());
        tbFile.setFileName(fileinfo.getOriginalFilename());
        tbFile.setFileSize(fileinfo.getSize());
        tbFile.setContentType(fileinfo.getContentType());
        int r = tbFileDAO.insert(tbFile);
        if (r != 1) {
            return BaseDataResult.failNoData("保存文件信息失败");
        }
        // 保存文件
        File path = new File(UPLOAD_PATH);
        File file = new File(UPLOAD_PATH, String.format(FILE_NAME, tbFile.getFid(), tbFile.getFileName()));
        try {
            // 确保文件所在的目录存在
            if (!path.isDirectory()) {
                path.mkdirs();
            }
            copy(fileinfo.getInputStream(), new FileOutputStream(file));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return BaseDataResult.ok(tbFile);
    }
}
